#include "mypaint.h"
#include <QColorDialog>
#include <QDebug>
#include <QFontDialog>
#include <QMenuBar>
#include <QApplication>
#include <math.h>
#include <QDateTime>
#include <ctime>
#include <QtMath>
#include <QPointF>

MyPaint::MyPaint(QWidget *parent) :
    QMainWindow(parent)
{
    //初始化界面
    setFocus();//使主界面获得焦点
    _lpress = false;//初始鼠标左键未按下
    _drawType = 0;//初始为什么都不画
    _drag = 0;//默认非拖拽模式
    _begin = pos();//拖拽的参考坐标，方便计算位移
    _openflag = 0;//初始不打开图片
    _cutFlag = 1;//初始不剪切
    _tEdit = new QTextEdit(this);//初始化文本输入框
    _tEdit->hide();//隐藏
    this->setGeometry(350,200,800,550);//设置窗体大小、位置
    setMouseTracking(true);//开启鼠标实时追踪，监听鼠标移动事件，默认只有按下时才监听
    this->setStyleSheet("background-color:white;");//设置背景白色
    penSize = 3;//画笔默认大小为2
    penColor = Qt::black;//画笔默认颜色为黑色
    fSize = 10;//默认字体大小10
    fColor = Qt::black;//默认字体颜色黑色
    fFont.setFamily("微软雅黑");//默认字体
    _tEdit->setFont(fFont);
    _tEdit->setTextColor(fColor);
    _tEdit->setFontPointSize(fSize);

    //创建动作
    QAction *openAction = new QAction(tr("&打开"), this);//打开动作
    openAction->setIcon(QIcon(":/images/打开文件.png"));//图标
    openAction->setShortcut(QKeySequence(tr("Ctrl+O")));//热键

    QAction *saveasAction = new QAction(tr("&另存为"), this);//另存为动作
    saveasAction->setIcon(QIcon(":/images/另存为.png"));//图标
    saveasAction->setShortcut(QKeySequence(tr("Ctrl+ALT+S")));//热键

    QAction *saveAction = new QAction(tr("&保存"), this);//保存动作
    saveAction->setIcon(QIcon(":/images/保存.png"));//图标
    saveAction->setShortcut(QKeySequence(tr("Ctrl+S")));//热键

    QAction *cut = new QAction(tr("&剪切"), this);//剪切
    cut->setIcon(QIcon(":/images/剪切.png"));
    QAction *penGunAction = new QAction(tr("&喷枪"), this);//喷枪
    penGunAction->setIcon(QIcon(":/images/Spray喷枪.png"));

    QAction *linesAction = new QAction(tr("&铅笔"), this);//铅笔动作
    linesAction->setIcon(QIcon(":/images/铅笔.png"));//图标
    linesAction->setShortcut(QKeySequence(tr("Ctrl+P")));//热键

    QAction *brush = new QAction(tr("&刷子"), this);//刷子
    brush->setIcon(QIcon(":/images/刷子.png"));

    QAction *waterpen = new QAction(tr("&记号笔"), this);//记号笔
    waterpen->setIcon(QIcon(":/images/记号笔.png"));

    QAction *rubber = new QAction(tr("&橡皮"), this);//橡皮
    rubber->setIcon(QIcon(":/images/橡皮.png"));

    QAction *lineAction = new QAction(tr("&直线"), this);//直线动作
    lineAction->setIcon(QIcon(":/images/直线.png"));//图标
    lineAction->setShortcut(QKeySequence(tr("Ctrl+L")));//热键

    QAction *rectAction = new QAction(tr("&矩形"), this);//矩形动作
    rectAction->setIcon(QIcon(":/images/矩形.png"));//图标
    rectAction->setShortcut(QKeySequence(tr("Ctrl+R")));//热键

    QAction *ellipseAction = new QAction(tr("&椭圆"), this);//椭圆动作
    ellipseAction->setIcon(QIcon(":/images/圆.png"));//图标
    ellipseAction->setShortcut(QKeySequence(tr("Ctrl+E")));//热键

    QAction *textAction = new QAction(tr("&文字"), this);//文字动作
    textAction->setIcon(QIcon(":/images/文本.png"));//图标
    textAction->setShortcut(QKeySequence(tr("Ctrl+T")));//热键

    QAction *_exit = new QAction(tr("&退出"), this);//退出
    _exit->setIcon(QIcon(":/images/退出.png"));

    QAction *newFile = new QAction(tr("&新建"), this);//新建
    newFile->setIcon(QIcon(":/images/新建.png"));
    newFile->setShortcut(QKeySequence(tr("Ctrl+N")));

    QAction *bigger = new QAction(tr("&放大"), this);//放大
    bigger->setIcon(QIcon(":/images/放大.png"));
    bigger->setShortcut(QKeySequence(tr("Ctrl+B")));

    QAction *smaller = new QAction(tr("&缩小"), this);//缩小
    smaller->setIcon(QIcon(":/images/缩小.png"));
    smaller->setShortcut(QKeySequence(tr("Ctrl+-")));

    QAction *help = new QAction(tr("&帮助"), this);//帮助
    help->setIcon(QIcon(":/images/帮助.png"));

    QAction *originSizeAction = new QAction(tr("&还原窗口"), this);//复原窗口大小
    originSizeAction->setIcon(QIcon(":/images/原窗口大小.png"));
    originSizeAction->setShortcut(QKeySequence(tr("Shift+O")));

    QAction *closeFontSettings = new QAction(tr(""), this);//隐藏字体设置悬浮窗
    closeFontSettings->setShortcut(QKeySequence(tr("Shift+H")));

    QAction *selColor = new QAction(tr("&选择颜色"), this);//选择颜色
    selColor->setIcon(QIcon(":/images/选择颜色.png"));

    _sbox = new QSpinBox;//画笔大小
    _sbox->setMaximum(20);
    _sbox->setMinimum(1);
    _sbox->setValue(3);
    QSize sSize(150, 25);
    _sbox->setFixedSize(sSize);


    //创建工具栏
    QToolBar *tbar = addToolBar(tr("工具栏"));
    tbar->setMovable(false);//工具栏不可移动
    tbar->setIconSize(QSize(25, 25));//设置动作图标的尺寸
    tbar->setStyleSheet("background-color:rgb(230,230,230)");//背景色
    tbar->addSeparator();
    tbar->addAction(saveasAction);
    tbar->addAction(saveAction);//添加到工具栏
    tbar->addAction(cut);
    tbar->addAction(linesAction);//添加到工具栏
    tbar->addAction(brush);
    tbar->addAction(penGunAction);
    tbar->addAction(waterpen);
    tbar->addAction(rubber);
    tbar->addAction(lineAction);//添加到工具栏
    tbar->addAction(rectAction);
    tbar->addAction(ellipseAction);
    tbar->addAction(textAction);
    tbar->addAction(bigger);
    tbar->addAction(smaller);
    tbar->addAction(selColor);
    tbar->addWidget(_sbox);

    //创建菜单栏
    QMenuBar *bar = menuBar();
    setMenuBar(bar);
    bar->setStyleSheet("QMenu::item:selected{background-color:rgb(0,100,200);}\
                             QMenuBar{background-color:rgb(245,245,245);}");
    QMenu *fileMenu = bar->addMenu("文件");
    fileMenu->addAction(newFile);
    fileMenu->setStatusTip("新建文件");
    fileMenu->addSeparator();
    fileMenu->addAction(openAction);
    fileMenu->addSeparator();
    fileMenu->addAction(saveAction);
    fileMenu->addSeparator();
    fileMenu->addAction(saveasAction);
    fileMenu->addSeparator();
    fileMenu->addAction(_exit);
    fileMenu->addSeparator();
    QMenu *toolMenu = bar->addMenu("工具");
    toolMenu->addAction(cut);
    toolMenu->addSeparator();
    toolMenu->addAction(linesAction);
    toolMenu->addSeparator();
    toolMenu->addAction(rubber);
    toolMenu->addSeparator();
    toolMenu->addAction(brush);
    toolMenu->addSeparator();
    toolMenu->addAction(penGunAction);
    toolMenu->addSeparator();
    toolMenu->addAction(waterpen);
    toolMenu->addSeparator();
    toolMenu->addAction(lineAction);
    toolMenu->addSeparator();
    toolMenu->addAction(rectAction);
    toolMenu->addSeparator();
    toolMenu->addAction(ellipseAction);
    toolMenu->addSeparator();
    toolMenu->addAction(textAction);
    fileMenu->addSeparator();
    QMenu *checkMenu = bar->addMenu("查看");
    checkMenu->addAction(bigger);
    checkMenu->addSeparator();
    checkMenu->addAction(smaller);
    checkMenu->addSeparator();
    checkMenu->addAction(originSizeAction);
    QMenu *helpMenu = bar->addMenu("帮助");
    helpMenu->addAction(help);
    fileMenu->addSeparator();

    _Rmenu = new QMenu(this);//创建右键菜单
    _Rmenu->addAction(originSizeAction);
    _Rmenu->addAction(tr("保存  \tCtrl+S"), this, SLOT(SavePic()));//添加菜单动作
    _Rmenu->addAction(tr("帮助  \tCtrl+H"), this, SLOT(help_clicked()));//添加菜单动作
    _Rmenu->addAction(tr("退出  \tALT+F4"), this, SLOT(close()));//添加菜单动作
    _Rmenu->setStyleSheet("background-color:rgb(230,230,230)");//设置背景色

    //连接信号与槽函数
    connect(newFile, &QAction::triggered, this, &MyPaint::NewFile);
    connect(linesAction, SIGNAL(triggered()), this, SLOT(Lines()));
    connect(rubber, &QAction::triggered, this, &MyPaint::Rubber);
    connect(rectAction, SIGNAL(triggered()), this, SLOT(Rects()));
    connect(ellipseAction, SIGNAL(triggered()), this, SLOT(Ellipses()));
    connect(lineAction, SIGNAL(triggered()), this, SLOT(Line()));
    connect(saveAction, SIGNAL(triggered()), this, SLOT(SavePic()));
    connect(openAction, SIGNAL(triggered()), this, SLOT(OpenPic()));
    connect(textAction, SIGNAL(triggered()), this, SLOT(Texts()));
    connect(_tEdit, SIGNAL(textChanged()), this, SLOT(AddTexts()));
    connect(saveasAction, SIGNAL(triggered()), this, SLOT(SaveasPic()));
    connect(_exit, &QAction::triggered, this, [=](){
        fs->close();
        this->close();
    });
    connect(help, SIGNAL(triggered()), this, SLOT(help_clicked()));
    connect(cut, &QAction::triggered, this, &MyPaint::Cut);
    connect(brush, &QAction::triggered, this, &MyPaint::Brush);
    connect(waterpen, SIGNAL(triggered()), this, SLOT(WaterPen()));
    connect(_sbox, static_cast<void(QSpinBox::*)(int)>(&QSpinBox::valueChanged),[=](int value){
               penSize = value;
    });//获取画笔大小
    connect(selColor, &QAction::triggered, this, &MyPaint::color);
    connect(bigger, &QAction::triggered, this, [=](){
       scale = scale * 1.1;
       update();
    });//画板放大
    connect(smaller, &QAction::triggered, this, [=](){
        scale = scale * 0.9;
        update();
    });//画板缩小
    connect(originSizeAction, &QAction::triggered, this, [=](){
       scale = 1.0;
       update();
    });//还原默认大小
    connect(penGunAction, &QAction::triggered, this, &MyPaint::BrushGun);

    //字体浮窗
    fs = new FontSettings;
    //字体信息建立连接
    connect(fs, &FontSettings::sendFontSize, this, &MyPaint::recvFontSize);
    connect(fs, &FontSettings::sendFontType, this, &MyPaint::recvFonttype);
    connect(fs, &FontSettings::sendFontColor, this, &MyPaint::recvFontColor);


}

void MyPaint::Lines()
{
    _drawType = 1;//铅笔
    _tEdit->hide();//文本框隐藏
}

void MyPaint::Rects()
{
    _drawType = 2;//矩形
    _tEdit->hide();

}

void MyPaint::Ellipses()
{
    _drawType = 3;//椭圆
    _tEdit->hide();
}

void MyPaint::Line()
{
    _drawType = 4;//直线
    _tEdit->hide();
}

void MyPaint::Texts()
{
    _drawType = 5;//文字
}

void MyPaint::Rubber()
{
    _drawType = 6;//橡皮
    _tEdit->hide();
}

void MyPaint::Cut()
{
    _drawType = 7;//剪切
    _tEdit->hide();
}

void MyPaint::Brush()
{
    _drawType = 8;//刷子
    _tEdit->hide();
}

void MyPaint::BrushGun()
{
    _drawType = 9;//喷枪
    _tEdit->hide();
}

void MyPaint::WaterPen()
{
    _drawType = 10;
    _tEdit->hide();
}

void MyPaint::AddTexts()//当输入框文本改变时调用
{
    if (scale != 1.0) return ;
    QString& last = _text.last();//拿到最后一个文本
    last = _tEdit->toPlainText();//将输入框文本作为文本
    //解决颜色不匹配问题
    if (_textColor.last() != fColor) {
        _textColor.last() = fColor;
    }
    if (_textSize.last() != fSize) {
        _textSize.last() = fSize;
    }
    if (_textFont.last() != fFont) {
        _textFont.last() = fFont;
    }
}

//颜色选择
void MyPaint::color()
{
    penColor =  QColorDialog::getColor(Qt::black,this, tr("选择颜色"));
    penColor.setAlpha(100);
}

//新建文件
void MyPaint::NewFile()
{
    fs->setVisible(false);
    SavePic();
    //出始化
    _lines.clear();
    _linesColor.clear();
    _lineSize.clear();
    _waterPens.clear();
    _waterPensSize.clear();
    _waterPensColor.clear();
    _rubber.clear();
    _rubberSize.clear();
    _rects.clear();
    _rectsColor.clear();
    _rectsSize.clear();
    _ellipse.clear();
    _ellipseColor.clear();
    _ellipseSize.clear();
    _line.clear();
    _lineColor.clear();
    _lineSize.clear();
    _text.clear();
    _tpoint.clear();
    _shape.clear();
    _lpress = false;
    _drawType = 0;
    penSize = _sbox->value();
    _drag = 0;
    scale = 1.0;
    _begin = pos();
    _openflag = 0;
    _tEdit->hide();
    //剪切板
    _cutImage.clear();
    _cutAfter.clear();
    _cutBefore.clear();
    _cutFlag = 0;
    //刷子
    _brush.clear();
    _brushSize.clear();
    _brushColor.clear();
    _brushSpeed.clear();
    _brushTime.clear();
    //喷枪
    _penGun.clear();
    _penGunSize.clear();
    _penGunColor.clear();
    _pointPenPoint.clear();
    _pointNumber.clear();

}

//接受字体颜色
void MyPaint::recvFontColor(QColor fColor_)
{
    fColor = fColor_;
    _tEdit->setTextColor(fColor);
}

//接受字体类型
void MyPaint::recvFonttype(QFont fFont_)
{
    fFont = fFont_;
    _tEdit->setFont(fFont);
}

//接受字体大小
void MyPaint::recvFontSize(int fSize_)
{
    fSize = fSize_;
    _tEdit->setFontPointSize(fSize);
}

//计算两点之间的速度
double MyPaint::getSpeed(QPoint a, QPoint b, long time)
{
    double len = sqrt(1.0*(a.rx()-b.rx())*(a.rx()-b.rx()) + 1.0*(a.ry()-b.ry())*(a.ry()-b.ry()));
    return len/time;
}

//跳转另存为界面
void MyPaint::SaveasPic()
{
    fs->setVisible(false);
    SavePicture *savePicture = new SavePicture();
    savePicture->move(600,300);
    savePicture->show();
    connect(savePicture, &SavePicture::savejpg, this, &MyPaint::savetypejpg);//信号连接
    connect(savePicture, &SavePicture::savepng, this, &MyPaint::savetypepng);
    connect(savePicture, &SavePicture::savegif, this, &MyPaint::savetypegif);
}

//保存为jpg图片
void MyPaint::savetypejpg()
{
    QString fileName = QFileDialog::getSaveFileName(this, tr("保存"), "new.jpg", "Image (*.jpg)");

    if (fileName.length() > 0)
    {
        _tEdit->hide();//防止文本输入框显示时，将文本框保存到图片
        QPixmap pixmap(size());//新建窗体大小的pixmap
        QPainter painter(&pixmap);//将pixmap作为画布
        painter.fillRect(QRect(0, 0, size().width(), size().height()), Qt::white);//设置绘画区域、画布颜色
        this->render(&painter);//将窗体渲染到painter，再由painter画到画布
        pixmap.copy(QRect(0,80,size().width(),size().height()-80)).save(fileName);//不包含工具栏
    }
}

//保存为png图片
void MyPaint::savetypepng()
{
    QString fileName = QFileDialog::getSaveFileName(this, tr("保存"), "new.png", "Image (*.png)");

    if (fileName.length() > 0)
    {
        _tEdit->hide();//防止文本输入框显示时，将文本框保存到图片
        QPixmap pixmap(size());//新建窗体大小的pixmap
        QPainter painter(&pixmap);//将pixmap作为画布
        painter.fillRect(QRect(0, 0, size().width(), size().height()), Qt::white);//设置绘画区域、画布颜色
        this->render(&painter);//将窗体渲染到painter，再由painter画到画布
        pixmap.copy(QRect(0,80,size().width(),size().height()-80)).save(fileName);//不包含工具栏
    }
}

//保存为gif图片
void MyPaint::savetypegif()
{
    QString fileName = QFileDialog::getSaveFileName(this, tr("保存"), "new.bmp", "Image (*.bmp)");

    if (fileName.length() > 0)
    {
        _tEdit->hide();//防止文本输入框显示时，将文本框保存到图片
        QPixmap pixmap(size());//新建窗体大小的pixmap
        QPainter painter(&pixmap);//将pixmap作为画布
        painter.fillRect(QRect(0, 0, size().width(), size().height()), Qt::white);//设置绘画区域、画布颜色
        this->render(&painter);//将窗体渲染到painter，再由painter画到画布
        pixmap.copy(QRect(0,80,size().width(),size().height()-80)).save(fileName);//不包含工具栏
    }
}

void MyPaint::SavePic()
{
    fs->setVisible(false);
    //弹出文件保存对话框
    QString fileName = QFileDialog::getSaveFileName(this, tr("保存"), "new.jpg", "Image (*.jpg *.png *.bmp)");

    if (fileName.length() > 0)
    {
        _tEdit->hide();//防止文本输入框显示时，将文本框保存到图片
        QPixmap pixmap(size());//新建窗体大小的pixmap
        QPainter painter(&pixmap);//将pixmap作为画布
        painter.fillRect(QRect(0, 0, size().width(), size().height()), Qt::white);//设置绘画区域、画布颜色
        this->render(&painter);//将窗体渲染到painter，再由painter画到画布
        pixmap.copy(QRect(0,80,size().width(),size().height()-80)).save(fileName);//不包含工具栏
    }
}

void MyPaint::OpenPic()
{
    fs->setVisible(false);
    //弹出文件打开对话框
    QString picPath = QFileDialog::getOpenFileName(this,tr("打开"),"","Image Files(*.jpg *.png)");
    if(!picPath.isEmpty())//用户选择了文件
    {
        QPixmap pix;
        pix.load(picPath);//加载图片
        QPainter p(&_pixmap);
        p.drawPixmap(0,80,pix);//添加工具栏的空间
        _openflag = 1;//设置文件打开标志
        update();//触发窗体重绘，将图片画到窗体
    }
}

void MyPaint::help_clicked()
{
    help = new Help(this);
    help->setModal(false);
    help->show();
}

/***********************************************************************
  名称：paintEvent
  说明：画图事件
************************************************************************/
void MyPaint::paintEvent(QPaintEvent *)
{
    if(_openflag == 0)//不是打开图片的，每一次新建一个空白的画布
    {
        _pixmap = QPixmap(size());//新建pixmap
        _pixmap.fill(Qt::white);//背景色填充为白色
    }
    QPixmap pix = _pixmap;//以_pixmap作为画布
    QPainter p(&pix);//将_pixmap作为画布

    int i1=0,i2=0,i3=0,i4=0,i5=0,i6=0,i7=0,i8=0,i9=0,i10=0;//各种图形的索引
    int index=0;//记录数组下表

    for(int c = 0;c<_shape.size();++c)//控制用户当前所绘图形总数
    {
        if(_shape.at(c) == 1)//线条
        {
            QPainterPath path;
            const QVector<QPoint>& line = _lines.at(i1);//取出一条线条
            //设置画笔
            QPen pen(_linesColor.at(i1), _linesSize.at(i1));
            p.setPen(pen);
            path.moveTo(line.at(0));
            for(int j=0; j<line.size(); ++j)//将线条的所有线段描绘出
            {

                path.lineTo(line.at(j));
            }
            i1++;
            p.drawPath(path);
        }
        else if(_shape.at(c) == 2)//矩形
        {
            QPen pen(_rectsColor.at(i2), _rectsSize.at(i2));
            p.setPen(pen);
            p.drawRect(_rects.at(i2));
            i2++;
        }
        else if(_shape.at(c) == 3)//椭圆
        {
            QPen pen(_ellipseColor.at(i3), _ellipseSize.at(i3));
            p.setPen(pen);
            p.drawEllipse(_ellipse.at(i3));
            i3++;
        }
        else if(_shape.at(c) == 4)//直线
        {
            QPen pen(_lineColor.at(i4), _lineSize.at(i4));
            p.setPen(pen);
            p.drawLine(_line.at(i4).topLeft(),_line.at(i4).bottomRight());
            i4++;
        }
        else if(_shape.at(c) == 5)//文本
        {
            QFont _font = _textFont.at(i5);
            _font.setPointSize(_textSize.at(i5));
            p.setFont(_font);
            p.setPen(_textColor.at(i5));
            p.drawText(_tpoint.at(i5),_text.at(i5));
            i5++;
        }
        else if (_shape.at(c) == 6)//橡皮
        {
            const QVector<QPoint>& rb = _rubber.at(i6);
            QPen pen(Qt::white, _rubberSize.at(i6));
            i6++;
            p.setPen(pen);
            for (int j=0; j<rb.size()-1; ++j)
            {
                p.drawLine(rb.at(j), rb.at(j+1));
            }
        }
        else if (_shape.at(c) == 7)//剪切
        {
            QPen pen(Qt::blue, 1);
            pen.setStyle(Qt::DashLine);
            p.setPen(pen);
            if (_drawType != 7) {
                pen.setColor(Qt::white);
                p.setPen(pen);
                p.drawImage(_cutAfter.at(i7), _cutImage.at(i7));
                p.drawRect(_cutAfter.at(i7));
            } else {
                if (_cutImage.size()-1 == i7 && _cutFlag){
                    p.drawImage(_cutAfter.at(i7), _cutImage.at(i7));
                } else if (_cutImage.size()-1 > i7) {
                    p.drawImage(_cutAfter.at(i7), _cutImage.at(i7));
                }
                if ((_lpress) && _cutAfter.size()-1 == i7) {
                    p.drawRect(_cutAfter.at(i7));
                }
                else {
                    pen.setColor(Qt::white);
                    p.setPen(pen);
                    p.drawRect(_cutAfter.at(i7));
                }
            }
            QBrush brush(Qt::white);
            p.setPen(pen);
            p.setBrush(brush);
            if (_drawType != 7) {
                p.drawRect(_cutBefore.at(i7));
            } else {
                if (_cutFlag && _cutBefore.size()-1 == i7) {
                    p.drawRect(_cutBefore.at(i7));
                } else if (_cutBefore.size()-1 > i7){
                    p.drawRect(_cutBefore.at(i7));
                }
            }
            i7++;
            brush.setStyle(Qt::NoBrush);
            p.setBrush(brush);
        }
        else if (_shape.at(c) == 8) //刷子
        {
            const QVector<QPoint>& line = _brush.at(i8);
            const QVector<double>& _speed = _brushSpeed.at(i8);
            QPen pen(_brushColor.at(i8));
            int _pS = _brushSize.at(i8);
            double _pSize(_brushSize.at(i8++));
            double maxSpeed = 0;
            for (int j=0; j < _speed.size(); j++) {
                if (maxSpeed < _speed.at(j)) {
                    maxSpeed = _speed.at(j);
                }
            }
            int _pre = 2;
            for (int j=0; j<line.size()-1; j++) {
                int _size((1-_speed.at(j)/maxSpeed)*_pSize);
                if (j == 0) _pre = _size;
                if (_size > _pre) _size = _pre+1;
                else if (_size < _pre) _size = _pre-1;
                if (_size <= 0) _size = 1;
                if (_size > _pS) _size = _pS;
                pen.setWidth(_size);
                p.setPen(pen);
                p.drawLine(line.at(j), line.at(j+1));
                _pre = _size;
            }
        }
        else if (_shape.at(c) == 9) //喷枪
        {
            const QVector<QPoint>& line = _penGun.at(i9);//取出一条线条
            //设置画笔
            QPen pen(_penGunColor.at(i9), 2);
            p.setPen(pen);
            for(int j=0; j<line.size(); ++j)//将线条的所有线段描绘出
            {
                if (index > _pointNumber.size()-1) {
                    qsrand(QTime(0,0,0).secsTo(QTime::currentTime()));
                    int num = qrand()%10+10;//随机生成点的数量
                    _pointNumber.append(num);
                    QVector<QPointF> points_;
                    _pointPenPoint.append(points_);
                    QVector<QPointF>& lastPoints = _pointPenPoint.last();
                    int cnt_ = 0;
                    while (cnt_ <= num) {
                        double n = (double)(qrand()%_penGunSize.at(i9));//随机生成半径
                        double x = (double)(qrand()%_penGunSize.at(i9));//随机生成坐标
                        double y = sqrt(fabs(n*n-x*x));
                        QPointF tmp;
                        if(cnt_%4==0) {
                            tmp = line.at(j)+QPointF(x, y);
                        } else if (cnt_%4==1) {
                            tmp = line.at(j)+QPointF(-x, y);
                        } else if (cnt_%4==2) {
                            tmp = line.at(j)+QPointF(x, -y);
                        }else {
                            tmp = line.at(j)+QPointF(-x, -y);
                        }
                        p.drawPoint(tmp);
                        lastPoints.append(tmp);
                        cnt_++;
                        index++;
                    }
                } else {
                    const QVector<QPointF>& points_ = _pointPenPoint.at(index);
                    for (int var = 0; var < _pointNumber.at(index); ++var) {
                        p.drawPoint(points_.at(var));
                    }
                }
                p.drawPoint(line.at(j));
                index++;
            }
            i9++;
        }
        else if(_shape.at(c) == 10)//记号笔
        {
            QPainterPath path;
            const QVector<QPoint>& line = _waterPens.at(i10);//取出一条线条
            path.moveTo(line.at(0));
            //设置画笔
            QPen pen(_waterPensColor.at(i10), _waterPensSize.at(i10));
            i10++;
            p.setPen(pen);
            for(int j=0; j<line.size(); ++j)//将线条的所有线段描绘出
            {
                path.lineTo(line.at(j));
            }
            p.drawPath(path);
        }

    }
    p.end();
    p.begin(this);//将当前窗体作为画布
    pix = pix.scaled(size()*scale, Qt::KeepAspectRatio, Qt::SmoothTransformation);//将窗体缩放
    p.drawPixmap(0,0, pix);//将pixmap画到窗体
}

/***********************************************************************
  名称：mousePressEvent
  说明：鼠标点击事件
************************************************************************/
void MyPaint::mousePressEvent(QMouseEvent *e)
{
    //_cutFlag = 0;
    if (scale != 1.0) return ;
    if(e->button() == Qt::LeftButton)//当鼠标左键按下
    {
        if (_drawType != 5) fs->setVisible(false);
        if(_drawType == 1)//线条(铅笔)
        {
            _lpress = true;//左键按下标志
            QVector<QPoint> line;//鼠标按下，新的线条开始
            _lines.append(line);//将新线条添加到线条集合
            penColor.setAlpha(255);
            _linesColor.append(penColor);
            _linesSize.append(penSize);
            QVector<QPoint>& lastLine = _lines.last();//拿到新线条
            lastLine.append(e->pos());//记录鼠标的坐标(新线条的开始坐标)
            _shape.append(1);
        }
        else if(_drawType == 2)//矩形
        {
            _lpress = true;//左键按下标志
            if(!_drag)//非拖拽模式
            {
                QRect rect;//鼠标按下，矩形开始
                _rects.append(rect);//将新矩形添加到矩形集合
                penColor.setAlpha(255);
                _rectsColor.append(penColor);
                _rectsSize.append(penSize);
                QRect& lastRect = _rects.last();//拿到新矩形
                lastRect.setTopLeft(e->pos());//记录鼠标的坐标(新矩形的左上角坐标)
                 _shape.append(2);
            }
            else if(_rects.last().contains(e->pos()))//拖拽模式、如果在矩形内按下
            {
                _begin = e->pos();//记录拖拽开始的坐标位置,方便计算位移

            }

        }
        else if(_drawType == 3)//椭圆
        {
            _lpress = true;//左键按下标志
            if(!_drag)//非拖拽模式
            {
                QRect rect;//鼠标按下，椭圆开始
                _ellipse.append(rect);//将新椭圆添加到椭圆集合
                penColor.setAlpha(255);
                _ellipseColor.append(penColor);
                _ellipseSize.append(penSize);
                QRect& lastEllipse = _ellipse.last();//拿到新椭圆
                lastEllipse.setTopLeft(e->pos());//记录鼠标的坐标(新椭圆的左上角坐标)
                 _shape.append(3);
            }
            else if(_ellipse.last().contains(e->pos()))//如果在椭圆内按下
            {
                _begin = e->pos();//记录拖拽开始的坐标位置

            }
        }
        else if(_drawType == 4)//直线
        {
            _lpress = true;//左键按下标志
            QRect rect;//鼠标按下，直线一端开始
            _line.append(rect);//将新直线添加到直线集合
            penColor.setAlpha(255);
            _lineColor.append(penColor);
            _lineSize.append(penSize);
            QRect& lastLine = _line.last();//拿到新直线
            lastLine.setTopLeft(e->pos());//记录鼠标的坐标(新直线开始一端坐标)
            _shape.append(4);
        }
        else if(_drawType == 5)//文字
        {
            fs->setVisible(true);
            update();//触发窗体重绘
            QPoint p;//鼠标按下，文字开始
            _tpoint.append(p);//将文字坐标添加到文字位置集合
            QPoint& lastp = _tpoint.last();//拿到新文字
            lastp = e->pos();//记录鼠标的坐标
            _tEdit->setGeometry(lastp.x()-6,lastp.y()-17,120,120);//设置文本框的位置、大小
            _tEdit->show();//显示文本输入框
            _text.append("");//添加文本到文本集合
            _textSize.append(fSize);
            _textColor.append(fColor);
            _textFont.append(fFont);
            _tEdit->clear();//因为全局只有一个，所以使用之前要清空
            _shape.append(5);
        }
        else if (_drawType == 6) //橡皮擦
        {
            _lpress = true;
            QVector<QPoint> rb;
            _rubber.append(rb);
            _rubberSize.append(penSize);
            QVector<QPoint>& lastRb = _rubber.last();
            lastRb.append(e->pos());
            _shape.append(6);
        }
        else if (_drawType == 7)
        {
            _cutFlag = 0;
            _lpress = true;
            if (!_drag) {
                QRect rect;
                _cutAfter.append(rect);
                _cutBefore.append(rect);
                QRect& lastRect = _cutAfter.last();
                QRect& lastRect_ = _cutBefore.last();
                lastRect.setTopLeft(e->pos());
                lastRect_.setTopLeft(e->pos());
                _shape.append(7);
            } else if (_cutAfter.last().contains(e->pos())) {
                _begin = e->pos();
            }
        }
        else if (_drawType == 8)
        {
            _lpress = true;
            QVector<QPoint> line;
            QVector<long> _time;
            QVector<double> _speed;
            _brush.append(line);
            _brushTime.append(_time);
            _brushSpeed.append(_speed);
            penColor.setAlpha(255);
            _brushColor.append(penColor);
            _brushSize.append(penSize);
            QVector<QPoint>& lastLine = _brush.last();
            QVector<long>& t = _brushTime.last();
            t.append(QDateTime::currentMSecsSinceEpoch());
            lastLine.append(e->pos());
            _shape.append(8);
        }
        else if (_drawType == 9) {//喷枪
            _lpress = true;
            QVector<QPoint> line;
            _penGun.append(line);
            _penGunSize.append(penSize);
            penColor.setAlpha(255);
            _penGunColor.append(penColor);
            QVector<QPoint>& lastLine = _penGun.last();
            lastLine.append(e->pos());
            _shape.append(9);
        }
        else if(_drawType == 10)
        {
            _lpress = true;//左键按下标志
            QVector<QPoint> line;//鼠标按下，新的线条开始
            _waterPens.append(line);//将新线条添加到线条集合
            penColor.setAlpha(50);
            _waterPensColor.append(penColor);
            _waterPensSize.append(penSize);
            QVector<QPoint>& lastLine = _waterPens.last();//拿到新线条
            lastLine.append(e->pos());//记录鼠标的坐标(新线条的开始坐标)
            _shape.append(10);
        }
    }
}

/***********************************************************************
  名称：mouseMoveEvent
  说明：鼠标移动事件
************************************************************************/
void MyPaint::mouseMoveEvent(QMouseEvent *e)
{
    if (scale != 1.0) return ;
   // _cutFlag = 0;
    if(_drag && ((_drawType == 2 && _rects.last().contains(e->pos()))
            || (_drawType == 3 && _ellipse.last().contains(e->pos()))
            || (_drawType == 7 && _cutAfter.last().contains(e->pos()))))
    {
        setCursor(Qt::SizeAllCursor);//拖拽模式下，并且在拖拽图形中，将光标形状改为十字
    }
    else
    {
        setCursor(Qt::ArrowCursor);//恢复原始光标形状
        _drag = 0;
    }

    if(_lpress)
    {
        if(_drawType == 1)//铅笔画线
        {
            if(_lines.size()<=0) return;//线条集合为空，不画线
            QVector<QPoint>& lastLine = _lines.last();//最后添加的线条，就是最新画的
            lastLine.append(e->pos());//记录鼠标的坐标(线条的轨迹)
            update();//触发窗体重绘
        }
        else if(_drawType == 2)
        {
            if(_drag == 0)//非拖拽
            {
                QRect& lastRect = _rects.last();//拿到新矩形
                lastRect.setBottomRight(e->pos());//更新矩形的右下角坐标
            }
            else//拖拽模式
            {
                QRect& lastRect = _rects.last();//拿到最后添加的矩形
                if(lastRect.contains(e->pos()))//在矩形的内部
                {
                    int dx = (e->pos().x()-_begin.x());//横向移动x
                    int dy = (e->pos().y()-_begin.y());//纵向移动y
                    lastRect = lastRect.adjusted(dx,dy,dx,dy);//更新矩形的位置
                    _begin = e->pos();//刷新拖拽点起始坐标
                }

            }
            update();//触发窗体重绘

        }
        else if(_drawType == 3)
        {
            if(_drag == 0)//非拖拽
            {
                QRect& lastEllipse = _ellipse.last();//拿到新椭圆
                lastEllipse.setBottomRight(e->pos());//更新椭圆的右下角坐标)

            }
            else//拖拽
            {
                QRect& lastEllipse = _ellipse.last();//拿到最后添加的矩形
                if(lastEllipse.contains(e->pos()))//在椭圆内部
                {
                    int dx = (e->pos().x()-_begin.x());//横向移动x
                    int dy = (e->pos().y()-_begin.y());//纵向移动y
                    lastEllipse = lastEllipse.adjusted(dx,dy,dx,dy);
                    _begin = e->pos();//刷新拖拽点起始坐标
                }

            }
            update();//触发窗体重绘
        }
        else if(_drawType == 4)
        {
            QRect& lastLine = _line.last();//拿到新直线
            lastLine.setBottomRight(e->pos());//更新直线另一端)
            update();//触发窗体重绘
        }
        else if(_drawType == 6)
        {
            if (_rubber.size()<=0) return;
            QVector<QPoint>& lastRb = _rubber.last();
            lastRb.append(e->pos());
            update();
        }
        else if (_drawType == 7)
        {
            if (_drag == 0)
            {
                QRect& lastRect = _cutAfter.last();
                lastRect.setBottomRight(e->pos());
            } else {
                QRect& lastRect = _cutAfter.last();
                if (lastRect.contains(e->pos())) {
                    int dx = (e->pos().x()-_begin.x());//横向移动x
                    int dy = (e->pos().y()-_begin.y());//纵向移动y
                    lastRect = lastRect.adjusted(dx,dy,dx,dy);//更新矩形的位置
                    _begin = e->pos();//刷新拖拽点起始坐标
                }
            }
            update();
        }
        else if (_drawType == 8) //刷子
        {
            if (_brush.size() <= 0) return ;
            QVector<QPoint>& lastLine = _brush.last();
            QVector<long>& lastTime = _brushTime.last();
            QVector<double>& lastSpeed = _brushSpeed.last();
            lastSpeed.append(getSpeed(lastLine.last(), e->pos(), (QDateTime::currentMSecsSinceEpoch()-lastTime.last())));
            lastLine.append(e->pos());
            lastTime.append(QDateTime::currentMSecsSinceEpoch());
            update();
        }
        else if (_drawType == 9) //喷枪
        {
            if (_penGun.size()<=0) return ;
            QVector<QPoint>& lastLine = _penGun.last();
            lastLine.append(e->pos());
            update();
        }
        else if(_drawType == 10)//铅笔画线
        {
            if(_waterPens.size()<=0) return;//线条集合为空，不画线
            QVector<QPoint>& lastLine = _waterPens.last();//最后添加的线条，就是最新画的
            lastLine.append(e->pos());//记录鼠标的坐标(线条的轨迹)
            update();//触发窗体重绘
        }

    }

}

/***********************************************************************
  名称：mouseReleaseEvent
  说明：鼠标释放事件
************************************************************************/
void MyPaint::mouseReleaseEvent(QMouseEvent *e)
{
    if (scale != 1.0) return ;
    //_cutFlag = 0;
    if(_lpress)
    {
        if(_drawType == 1)
        {
            QVector<QPoint>& lastLine = _lines.last();//最后添加的线条，就是最新画的
            lastLine.append(e->pos());//记录线条的结束坐标
            _lpress = false;//标志左键释放
        }
        else if(_drawType == 2)
        {
            QRect& lastRect = _rects.last();//拿到新矩形
            if(!_drag)
            {
                lastRect.setBottomRight(e->pos());//不是拖拽时，更新矩形的右下角坐标)
                //刚画完矩形，将光标设置到新矩形的中心位置，并进入拖拽模式
                this->cursor().setPos(this->cursor().pos().x()-lastRect.width()/2,this->cursor().pos().y()-lastRect.height()/2);
                _drag = 1;

            }
            _lpress = false;

        }
        else if(_drawType == 3)
        {
            QRect& lastEllipse = _ellipse.last();//拿到新椭圆
            if(!_drag)
            {
                lastEllipse.setBottomRight(e->pos());//不是拖拽时，更新椭圆的右下角坐标)
                //刚画完椭圆，将光标设置到新椭圆的中心位置，并进入拖拽模式
                this->cursor().setPos(this->cursor().pos().x()-lastEllipse.width()/2,this->cursor().pos().y()-lastEllipse.height()/2);
                _drag = 1;

            }
            _lpress = false;
        }
        else if(_drawType == 4)
        {
            QRect& lastLine = _line.last();//拿到新矩形
            lastLine.setBottomRight(e->pos());//更新矩形的右下角坐标)
            _lpress = false;

        }
        else if (_drawType == 6)
        {
            QVector<QPoint>& lastRb = _rubber.last();
            lastRb.append(e->pos());
            _lpress = false;
        }
        else if (_drawType == 7)
        {
            QRect& lastRect = _cutAfter.last();
            QRect& lastRect_ = _cutBefore.last();
            if (!_drag) {
                lastRect.setBottomRight(e->pos());
                lastRect_.setBottomRight(e->pos());
                QPixmap pixmap(size());//新建窗体大小的pixmap
                QPainter painter(&pixmap);//将pixmap作为画布
                painter.fillRect(QRect(0, 80, size().width(), size().height()-80), Qt::white);//设置绘画区域、画布颜色
                this->render(&painter);//将窗体渲染到painter，再由painter画到画布
                QPixmap cropped = pixmap.copy(QRect(_cutBefore.last()));
                QImage image(cropped.toImage());
                _cutImage.append(image);
                this->cursor().setPos(this->cursor().pos().x()-lastRect.width()/2,this->cursor().pos().y()-lastRect.height()/2);
                _cutFlag = 1;
                _drag = 1;
                update();
            }
            _lpress = false;
        }
        else if (_drawType == 8)
        {
            QVector<QPoint>& lastLine = _brush.last();
            QVector<long>& lastTime = _brushTime.last();
            QVector<double>& lastSpeed = _brushSpeed.last();
            lastLine.append(e->pos());
            lastTime.append(QDateTime::currentMSecsSinceEpoch());
            lastSpeed.append(getSpeed(lastLine.last(), e->pos(), (QDateTime::currentMSecsSinceEpoch()-lastTime.last())));
            _lpress = false;
        }
        else if (_drawType == 9)
        {
            QVector<QPoint>& lastLine = _penGun.last();
            lastLine.append(e->pos());
            _lpress = false;
        }
        else if(_drawType == 10)
        {
            QVector<QPoint>& lastLine = _waterPens.last();//最后添加的线条，就是最新画的
            lastLine.append(e->pos());//记录线条的结束坐标
            _lpress = false;//标志左键释放
        }
    }
}

/***********************************************************************
  名称：contextMenuEvent
  说明：右键菜单事件
************************************************************************/
void MyPaint::contextMenuEvent(QContextMenuEvent *)  //右键菜单事件
{
    fs->setVisible(false);
    _Rmenu->exec(cursor().pos());//在光标位置弹出菜单
}

/***********************************************************************
  名称：keyPressEvent
  说明：按键事件
************************************************************************/
void MyPaint::keyPressEvent(QKeyEvent *e) //按键事件
{
    fs->setVisible(false);
     setFocus();//获取焦点
     //Ctrl+Z撤销
     if (e->key() == Qt::Key_Z && e->modifiers() == Qt::ControlModifier)
     {
         if(_shape.size()>0)
         {
             int cnt = 0;
             switch(_shape.last())
             {
             case 1: _lines.pop_back();
                 _linesColor.pop_back();
                 _linesSize.pop_back();
                 break;
             case 2: _rects.pop_back();
                 _rectsColor.pop_back();
                 _rectsSize.pop_back();
                 break;
             case 3: _ellipse.pop_back();
                 _ellipseColor.pop_back();
                 _ellipseSize.pop_back();
                 break;
             case 4: _line.pop_back();
                 _lineColor.pop_back();
                 _lineSize.pop_back();
                 break;
             case 5: _text.pop_back();
                 _textFont.pop_back();
                 _textSize.pop_back();
                 _textColor.pop_back();
                 _tpoint.pop_back();
                 break;
             case 6:_rubber.pop_back();
                 _rubberSize.pop_back();
                 break;
             case 7:_cutAfter.pop_back();
                 _cutBefore.pop_back();
                 _cutImage.pop_back();
                 break;
             case 8:_brush.pop_back();
                 _brushSize.pop_back();
                 _brushColor.pop_back();
                 _brushTime.pop_back();
                 if (_brushSpeed.size()>0) _brushSpeed.pop_back();
                 break;
             case 9:
                 _penGunSize.pop_back();
                 _penGunColor.pop_back();
                 cnt = _penGun.last().size();
                 _penGun.pop_back();
                 for (int j=0; j<cnt; j++){
                     _pointPenPoint.pop_back();
                     _pointNumber.pop_back();
                     if (_pointNumber.size()==0||_pointPenPoint.size()==0) break;
                 }
                 break;
             case 10:_waterPens.pop_back();
                 _waterPensSize.pop_back();
                 _waterPensColor.pop_back();
             }
             _shape.pop_back();
             _drag = 0;//设置为非拖拽模式
             update();
         }
     }
     else if (e->key() == Qt::Key_S && e->modifiers() == Qt::ControlModifier)//保存
     {
        SavePic();//Ctrl+S保存
     }
     else if (e->key() == Qt::Key_O && e->modifiers() == Qt::ShiftModifier) //还原窗口大小 Shift+O
     {
         scale = 1.0;
         update();
     }
     else if(e->key() == Qt::Key_H && e->modifiers() == Qt::ShiftModifier) //隐藏字体设置悬浮窗
     {
         fs->setVisible(false);
     }
}

/***********************************************************************
  名称：wheelEvent
  说明：
************************************************************************/
void MyPaint::wheelEvent(QWheelEvent *e)
{
    if (e->delta() > 0) {
        scale = scale * 1.01;
        update();
    } else {
        scale = scale * 0.99;
        update();
    }
}


